﻿using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data.SqlServerCe;
using KingOfCSharp.iHunter;

using KingOfCSharp.iHunter.Database;
using KingOfCSharp.iHunter.Database.MasterDataSetTableAdapters;

namespace KingOfCSharp.iHunter.Database.MasterDataSetTableAdapters
{
    partial class TableAdapterManager
    {
        static Dictionary<int, TableAdapterManager> instances;
        /// <summary>
        /// Initializes a new instance of the <see cref="TableAdapterManager"/> class.
        /// </summary>
        /// <remarks>
        /// This is a singleton type
        /// Do not use this method, use <see cref="TableAdapterManager.Instance"/> to get the instance
        /// </remarks>
        protected TableAdapterManager()
            : base()
        {
            MasterDataSetTableAdapters.AttachmentsTableAdapter attachmentsTableAdapter;
            MasterDataSetTableAdapters.FiltersTableAdapter filtersTableAdapter;
            MasterDataSetTableAdapters.FoldersTableAdapter foldersTableAdapter;
            MasterDataSetTableAdapters.GlobalSettingsTableAdapter globalSettingsTableAdapter;
            MasterDataSetTableAdapters.MessagesTableAdapter messagesTableAdapter;
            MasterDataSetTableAdapters.PluginsTableAdapter pluginsTableAdapter;
            MasterDataSetTableAdapters.ChannelsTableAdapter channelsTableAdapter;
            MasterDataSetTableAdapters.MessageHeadersTableAdapter messageHeadersTableAdapter;

            attachmentsTableAdapter = new MasterDataSetTableAdapters.AttachmentsTableAdapter();
            filtersTableAdapter = new MasterDataSetTableAdapters.FiltersTableAdapter();
            foldersTableAdapter = new MasterDataSetTableAdapters.FoldersTableAdapter();
            globalSettingsTableAdapter = new MasterDataSetTableAdapters.GlobalSettingsTableAdapter();
            messagesTableAdapter = new MasterDataSetTableAdapters.MessagesTableAdapter();
            pluginsTableAdapter = new MasterDataSetTableAdapters.PluginsTableAdapter();
            channelsTableAdapter = new MasterDataSetTableAdapters.ChannelsTableAdapter();
            messageHeadersTableAdapter = new MessageHeadersTableAdapter();


            AttachmentsTableAdapter = attachmentsTableAdapter;
            ChannelsTableAdapter = channelsTableAdapter;
            FiltersTableAdapter = filtersTableAdapter;
            FoldersTableAdapter = foldersTableAdapter;
            GlobalSettingsTableAdapter = globalSettingsTableAdapter;
            MessagesTableAdapter = messagesTableAdapter;
            PluginsTableAdapter = pluginsTableAdapter;
            MessageHeadersTableAdapter = messageHeadersTableAdapter;
         
            BackupDataSetBeforeUpdate = false;
            UpdateOrder = MasterDataSetTableAdapters.TableAdapterManager.UpdateOrderOption.InsertUpdateDelete;
        }
        static TableAdapterManager()
        {
            instances = new Dictionary<int, TableAdapterManager>();

        }
        /// <summary>
        /// Gets the instance of the singleton type.
        /// </summary>
        /// <value>The instance.</value>
        public static TableAdapterManager Instance
        {
            get
            {
                TableAdapterManager instance = null;
                int tid = System.Threading.Thread.CurrentThread.ManagedThreadId;
                System.Threading.Monitor.Enter(instances);
                if (!instances.ContainsKey(tid))
                {
                    instance = new TableAdapterManager();
                    instances.Add(tid, instance);
                }
                else
                {
                    instance = instances[tid];
                }
                System.Threading.Monitor.Exit(instances);
                return instance;
            }
        }
    }
}

namespace KingOfCSharp.iHunter.Database.MasterDataSetTableAdapters
{
}

namespace KingOfCSharp.iHunter.Database
{

    partial class MasterDataSet : IDatabaseManager
    {
        partial class MessagesDataTable
        {
        }


        private static MasterDataSet masterDataset;

        /// <summary>
        /// Return a instance
        /// </summary>
        public static MasterDataSet Instance
        {
            get
            {
                if (MasterDataSet.masterDataset == null)
                    MasterDataSet.masterDataset = new MasterDataSet();
                return MasterDataSet.masterDataset;
            }
        }

        /// <summary>
        /// Load data to the DataSet
        /// </summary>
        public void Initialize()
        {
            this.Clear();
            //Check whether file exists
            string dbFilePath = Path.Combine((String)AppDomain.CurrentDomain.GetData("DataDirectory"), "Master.sdf");

            if (!File.Exists(dbFilePath))
                throw new System.IO.FileNotFoundException(string.Format("Cannot find database file {0}", dbFilePath));

            this.BeginInit();
            //Fill tables

            TableAdapterManager.Instance.GlobalSettingsTableAdapter.Fill(this.GlobalSettings);
            TableAdapterManager.Instance.FoldersTableAdapter.Fill(this.Folders);
            TableAdapterManager.Instance.MessageHeadersTableAdapter.Fill(this.MessageHeaders);
            TableAdapterManager.Instance.AttachmentsTableAdapter.Fill(this.Attachments);
            TableAdapterManager.Instance.PluginsTableAdapter.Fill(this.Plugins);
            TableAdapterManager.Instance.ChannelsTableAdapter.Fill(this.Channels);
            TableAdapterManager.Instance.FiltersTableAdapter.Fill(this.Filters);

            this.EndInit();

        }


        /// <summary>
        /// Determines whether the database file exists
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if the database file exists; otherwise, <c>false</c>.
        /// </returns>
        public bool IsDatabaseExist()
        {
            string dbFilePath = Path.Combine((String)AppDomain.CurrentDomain.GetData("DataDirectory"), "Master.sdf");
            return File.Exists(dbFilePath);

        }

        /// <summary>
        /// Create a new database
        /// </summary>
        public void CreateDataBase()
        {
            //Check whether db file already exists
            string dbFilePath = Path.Combine((String)AppDomain.CurrentDomain.GetData("DataDirectory"), "Master.sdf");


            Directory.CreateDirectory((String)AppDomain.CurrentDomain.GetData("DataDirectory"));
            
            //Create database
            SqlCeEngine engine = new SqlCeEngine(TableAdapterManager.Instance.Connection.ConnectionString);

            engine.CreateDatabase();


            //Before inserting data, you must create those tables. Data adapter will not create tables.
            SqlCeConnection conn = new SqlCeConnection(TableAdapterManager.Instance.Connection.ConnectionString);
            conn.Open();

            SqlCeCommand command = null;

           
            //Create  tables.
            command = conn.CreateCommand();



            //NOTE: Remove ROWGUID property, DataSet does not support it well.
            command.CommandText = "CREATE TABLE Attachments ("+
	            "Guid			uniqueidentifier		primary key not null,"+
	            "MessageGuid	uniqueidentifier		not null," +
	            "FileName		nvarchar(255)			not null," +
	            "Size			bigint					not null," +
	            "RemoteUrl		nvarchar(255)			not null," +
	            "LocalPath		nvarchar(255)			not null," +
	            "Description	nvarchar(200)			not null" +
                ");";
            command.ExecuteNonQuery();



            command.CommandText = "CREATE TABLE Channels (" +
	            "Guid			uniqueidentifier		primary key not null," +
	            "ProviderGuid	uniqueidentifier		not null," +
	            "FolderGuid		uniqueidentifier        not null," +
	            "Name			nvarchar(100)			not null," +
                "UpdateTime     datetime                not null," +
                "RefreshExists  int                     not null," +
                "Settings		ntext" +
                ");";
            command.ExecuteNonQuery();



            command.CommandText = "CREATE TABLE Filters (" +
                "Guid			uniqueidentifier		primary key not null," +
                "ProviderGuid	uniqueidentifier		not null," +
                "Enabled		bit						not null," +
                "Settings		ntext" +
                ");";
            command.ExecuteNonQuery();



            command.CommandText = "CREATE TABLE Folders (" +
                "Guid			uniqueidentifier		primary key not null," +
                "ParentGuid		uniqueidentifier," +
                "Name			nvarchar(100)			not null," +
                "Settings		ntext" +
                ");";
            command.ExecuteNonQuery();


            command.CommandText = "CREATE TABLE GlobalSettings (" +
                "Guid			uniqueidentifier		primary key not null," +
                "Settings		ntext" +
                ");";
            command.ExecuteNonQuery();


            command.CommandText = "CREATE TABLE Messages (" +
	            "Guid			uniqueidentifier		primary key not null," +
	            "FolderGuid		uniqueidentifier		not null," +
	            "ChannelGuid	uniqueidentifier		not null," +
	            "[Read]			bit						not null," +
	            "Title			nvarchar(100)			not null," +
	            "PublishTime	datetime				not null," +
	            "UpdateTime		datetime				not null," +
	            "Author			nvarchar(100)			not null," +
	            "Category		nvarchar(100)			not null," +
                "Content		ntext," +
	            "CustomFields	ntext," +
	            "ReplyGuid		uniqueidentifier        not null," +
                "Receiver		nvarchar(100),"+
                "ViewerGuid		uniqueidentifier        not null," +
                "EditorGuid		uniqueidentifier        not null," +
                "HashCode       int                     not null," +
                "OriginalFolderGuid uniqueidentifier	not null " +
                ");";
            command.ExecuteNonQuery();


            command.CommandText = "CREATE TABLE Plugins (" +
                "Guid			uniqueidentifier		primary key not null," +
                "Name			nvarchar(100)			not null," +
                "PluginPath		nvarchar(255)			not null," +
                "BinaryPath		nvarchar(255)			not null," +
                "DataStorePath	nvarchar(255)," +
                "BinaryType		int						not null," +
                "Description	nvarchar(200)," +
                "Settings		ntext," +
                "State		    int						not null" +
                ");";
            command.ExecuteNonQuery();


            // Create relations
            command.CommandText = @"ALTER TABLE Attachments
                ADD CONSTRAINT FK_Messages_Attachments
                FOREIGN KEY (MessageGuid)
                REFERENCES Messages(Guid)
                ON UPDATE CASCADE
                ON DELETE CASCADE;";
            command.ExecuteNonQuery();

            command.CommandText = @"ALTER TABLE Channels
                ADD CONSTRAINT FK_Folders_Channels
                FOREIGN KEY (FolderGuid)
                REFERENCES Folders(Guid)
                ON UPDATE CASCADE
                ON DELETE CASCADE;";
            command.ExecuteNonQuery();

            command.CommandText = @"ALTER TABLE Folders
                ADD CONSTRAINT FK_Folders_Folders
                FOREIGN KEY (ParentGuid)
                REFERENCES Folders(Guid)
                ON UPDATE NO ACTION
                ON DELETE NO ACTION;";
            command.ExecuteNonQuery();

            command.CommandText = @"ALTER TABLE Messages
                ADD CONSTRAINT FK_Folders_Messages
                FOREIGN KEY (FolderGuid)
                REFERENCES Folders(Guid)
                ON UPDATE CASCADE
                ON DELETE CASCADE;";
            command.ExecuteNonQuery();

//            command.CommandText = @"ALTER TABLE Messages
//                ADD CONSTRAINT FK_Messages_Messages
//                FOREIGN KEY (ReplyGuid)
//                REFERENCES Messages(Guid)
//                ON UPDATE NO ACTION
//                ON DELETE NO ACTION;";
//            command.ExecuteNonQuery();

            // Create indexes for Attachments
            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Attachments_MessageGuid
                ON Attachments(MessageGuid);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Attachments_FileName
                ON Attachments(FileName);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Attachments_Size
                ON Attachments(Size);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Attachments_RemoteUrl
                ON Attachments(RemoteUrl);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Attachments_LocalPath
                ON Attachments(LocalPath);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Attachments_Description
                ON Attachments(Description);";
            command.ExecuteNonQuery();


            // Create indexes for Folders
            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Folders_ParentGuid
                ON Folders(ParentGuid);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Folders_Name
                ON Folders(Name);";
            command.ExecuteNonQuery();

  
            // Create indexes for Attachments
            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_FolderGuid
                ON Messages(FolderGuid);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_ChannelGuid
                ON Messages(ChannelGuid);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_Read
                ON Messages([Read]);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_Title
                ON Messages(Title);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_PublishTime
                ON Messages(PublishTime);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_UpdateTime
                ON Messages(UpdateTime);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_Author
                ON Messages(Author);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_Category
                ON Messages(Category);";
            command.ExecuteNonQuery();

            command.CommandText = @"CREATE NONCLUSTERED
                INDEX IX_Messages_ReplyGuid
                ON Messages(ReplyGuid);";
            command.ExecuteNonQuery();





            conn.Close();

            
             //Create a xml doc for all "Settings"
            XmlDocument settingsXmlDoc = new XmlDocument();
            XmlElement rootElement = settingsXmlDoc.CreateElement("Settings");
            settingsXmlDoc.AppendChild(rootElement);

            string settings = settingsXmlDoc.OuterXml;

            //Insert value for table "GlobalSettings"
            GlobalSettingsRow grow = this.GlobalSettings.NewGlobalSettingsRow();

            grow.Guid = Guid.NewGuid();
            grow.Settings = settings;

            this.GlobalSettings.AddGlobalSettingsRow(grow);
            TableAdapterManager.Instance.GlobalSettingsTableAdapter.Update(grow);

            Guid rootGuid = Guid.NewGuid();

            FoldersRow row = this.Folders.NewFoldersRow();

            row = this.Folders.NewFoldersRow();
            row.Guid = rootGuid;
            row.SetParentGuidNull();
            row.Name = "[Root]";
            row.Settings = settings;
            this.Folders.AddFoldersRow(row);

            TableAdapterManager.Instance.FoldersTableAdapter.Update(row);
            //row.AcceptChanges();
            Guid inboxGuid = Guid.NewGuid();
            row = this.Folders.NewFoldersRow();
            row.Guid = inboxGuid;
            row.ParentGuid = rootGuid;
            row.Name = "[Inbox]";
            row.Settings = settings;
            this.Folders.AddFoldersRow(row);

            row = this.Folders.NewFoldersRow();
            row.Guid = Guid.NewGuid();
            row.ParentGuid = rootGuid;
            row.Name = "[Outbox]";
            row.Settings = settings;
            this.Folders.AddFoldersRow(row);

            row = this.Folders.NewFoldersRow();
            row.Guid = Guid.NewGuid();
            row.ParentGuid = rootGuid;
            row.Name = "[Drafts]";
            row.Settings = settings;
            this.Folders.AddFoldersRow(row);

            row = this.Folders.NewFoldersRow();
            row.Guid = Guid.NewGuid();
            row.ParentGuid = rootGuid;
            row.Name = "[Sent]";
            row.Settings = settings;
            this.Folders.AddFoldersRow(row);

            row = this.Folders.NewFoldersRow();
            row.Guid = Guid.NewGuid();
            row.ParentGuid = rootGuid;
            row.Name = "[Deleted]";
            row.Settings = settings;
            this.Folders.AddFoldersRow(row);

            TableAdapterManager.Instance.FoldersTableAdapter.Update(this.Folders);

            if (Folders.HasErrors)
            {
                System.Data.DataRow[] errorRows = this.Folders.GetErrors();
                for (int i = 0; i < errorRows.Length; i++)
                {
                    errorRows[i].RejectChanges();
                }
                throw new System.Data.DataException();
            }

            TableAdapterManager.Instance.MessagesTableAdapter.Update(this.Messages);

            if (Folders.HasErrors)
            {
                System.Data.DataRow[] errorRows = this.Folders.GetErrors();
                for (int i = 0; i < errorRows.Length; i++)
                {
                    errorRows[i].RejectChanges();
                }
                throw new System.Data.DataException();
            }
        }

        /// <summary>
        /// Delete a existing database
        /// </summary>
        public void DeleteDataBase()
        {
            string dbFilePath = Path.Combine((String)AppDomain.CurrentDomain.GetData("DataDirectory"), "Master.sdf");
            TableAdapterManager.Instance.Connection.Close();
            try
            {
                File.Delete(dbFilePath);
            }
            catch
            {
            }
        }

        partial class FiltersDataTable
        {
            
        }
    
        partial class PluginsDataTable
        {
        }
    
        partial class ChannelsDataTable
        {
            public ChannelsRow[] GetChannelsByFolderGuid(Guid guid)
            {
                return (ChannelsRow[])this.Select("FolderGuid=" + guid.ToString());
            }
        }

        partial class AttachmentsDataTable
        {
        }

        partial class AttachmentsRow : IAttachment
        {


        }

        partial class FoldersDataTable
        {
            /// <summary>
            /// The root folder.
            /// </summary>
            public FoldersRow Root
            {
                get
                {
                    return (this.Select(@"ParentGuid IS NULL"))[0] as FoldersRow;
                }
            }

            /// <summary>
            /// The [Inbox] folder.
            /// </summary>
            public FoldersRow Inbox
            {
                get
                {
                    return (this.Select(@"Name='[Inbox]'")[0]) as FoldersRow;
                }
            }

            /// <summary>
            /// The [Outbox] folder.
            /// </summary>
            public FoldersRow Outbox
            {
                get
                {
                    return (this.Select(@"Name='[Outbox]'")[0]) as FoldersRow;
                }
            }

            /// <summary>
            /// The [Sent Items] folder.
            /// </summary>
            public FoldersRow SentItems
            {
                get
                {
                    return (this.Select(@"Name='[Sent]'")[0]) as FoldersRow;
                }
            }

            /// <summary>
            /// The [Drafts] folder.
            /// </summary>
            public FoldersRow Drafts
            {
                get
                {
                    return (this.Select(@"Name='[Drafts]'")[0]) as FoldersRow;
                }
            }

            /// <summary>
            /// The [Deleted Items] folder.
            /// </summary>
            public FoldersRow DeletedItems
            {
                get
                {
                    return (this.Select(@"Name='[Deleted]'")[0]) as FoldersRow;
                }
            }
        }

        partial class MessageHeadersRow : IMessage
        {
            #region IMessage 成员

            public string Content
            {
                get
                {
                    throw new InvalidOperationException();
                }
                set
                {
                    throw new InvalidOperationException();
                }
            }

            public IDictionary<string, string> CustomFields
            {
                get { throw new InvalidOperationException(); }
            }

            public IFolder Folder
            {
                get { return FoldersRow; }
            }

            public ICollection<IAttachment> Attachments
            {
                get 
                {
                    List<AttachmentsRow> list = new List<AttachmentsRow>(GetAttachmentsRows());
                    foreach (var row in list)
                    {
                        if (row.RowState == System.Data.DataRowState.Deleted)
                            list.Remove(row);
                    }
                    return list.ToArray();
                }
            }

            public Guid ViewerGuid
            {
                get
                {
                    throw new InvalidOperationException();
                }
                set
                {
                    throw new InvalidOperationException();
                }
            }

            public Guid EditorGuid
            {
                get
                {
                    throw new InvalidOperationException();
                }
                set
                {
                    throw new InvalidOperationException();
                }
            }

            #endregion
        }

        partial class FoldersRow : IFolder
        {

            #region IFolder Members

            /// <summary>
            /// Parent folder.
            /// </summary>
            public IFolder Parent
            {
                get
                {

                    return FoldersRowParent;
                }
            }

            /// <summary>
            /// MessagesHeaders in the folder.
            /// </summary>
            public System.Collections.Generic.ICollection<IMessage> MessageHeaders
            {
                get 
                {
                    var messageHeadersRows = this.GetMessageHeadersRows();
                    List<MessageHeadersRow> list = new List<MessageHeadersRow>();
                    foreach (var msg in messageHeadersRows)
                    {
                        if (msg.RowState != System.Data.DataRowState.Deleted)
                            list.Add(msg);
                    }
                    return list.ToArray();
                }
            }

            /// <summary>
            /// Sub-folders in the folder.
            /// </summary>
            public System.Collections.Generic.ICollection<IFolder> SubFolders
            {
                get 
                {
                    var foldersRows = this.GetFoldersRows();
                    List<FoldersRow> list = new List<FoldersRow>();
                    foreach (var folder in foldersRows)
                    {
                        if (folder.RowState != System.Data.DataRowState.Deleted)
                            list.Add(folder);
                    }
                    return list.ToArray();
                }
            }


            ///// <summary>
            ///// Deletes the folder.
            ///// </summary>
            //public void DeleteSelf()
            //{
            //    if (this.IsSpecialFolder)
            //    {
            //        throw new InvalidOperationException("Cannot delete special folder.");
            //    }
            //    DeleteSelf(this);
            //    this.Delete();
            //    TableAdapterManager.Instance.FoldersTableAdapter.Update(this);
            //}

            //private void DeleteSelf(FoldersRow row)
            //{
            //    var childTable = TableAdapterManager.Instance.FoldersTableAdapter.GetDataByParentGuid(row.Guid);

            //    foreach (FoldersRow child in childTable)
            //    {
            //        System.Diagnostics.Debug.WriteLine(child.Name);
            //        DeleteSelf(child);
                    
            //    }
            //    row.Delete();

            //    //TableAdapterManager.Instance.FoldersTableAdapter.Update(row);
            //    TableAdapterManager.Instance.FoldersTableAdapter.Update(childTable);
            //}
            ///// <summary>
            ///// Move the folder to another parent folder.
            ///// </summary>
            ///// <param name="destParent">The destination.</param>
            //public void MoveTo(IFolder destParent)
            //{
            //    if (this.IsSpecialFolder)
            //    {
            //        throw new InvalidOperationException("Cannot move special folder.");
            //    }

            //    if (this.IsAncestorOf(destParent))
            //    {
            //        throw new InvalidOperationException("Cannot move ancestor to its child.");
            //    }

            //    this.ParentGuid = destParent.Guid;

            //    TableAdapterManager.Instance.FoldersTableAdapter.Update(this);
            //}

            /// <summary>
            /// Determines whether this is the root folder.
            /// </summary>
            /// <value></value>
            /// <returns>true if the folder is the root folder, otherwise false</returns>
            public bool IsRoot
            {
                get { return this.IsParentGuidNull(); }
            }

            /// <summary>
            /// Determines whether this is a special folder.
            /// Special folders are in the form "[xxx]".
            /// </summary>
            public bool IsSpecialFolder
            {
                get { return this.Name.StartsWith("[") && this.Name.EndsWith("]"); }
            }

            /// <summary>
            /// Determines whether this folder is another folder's ancestor.
            /// </summary>
            /// <param name="item">The folder to compare.</param>
            /// <returns>
            /// True if this folder is the ancestor of <paramref name="item"/>, or the two folders are the same one, returns true; otherwise false
            /// </returns>
            public bool IsAncestorOf(IFolder item)
            {
                do
                {
                    if (this.Guid == item.Guid)
                    {
                        return true;
                    }
                    item = item.Parent;
                } while (item != null);
                return false;
            }

            #endregion
        }

        partial class MessageHeadersDataTable
        {
 
        }

        partial class MessagesRow :IMessage
        {
            MessagesRowCustomFields customFields = null;
            
            internal string GetCustomField(string name)
            {
                if (this.CustomFields == null)
                    return null;

                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(this.CustomFields);
                XmlElement root = xmlDoc.DocumentElement;
                XmlElement field = root[name];
                if (field == null)
                {
                    return null;
                }
                else
                {
                    return field.InnerText;
                }
            }

            internal void SetCustomField(string name, string value)
            {
                
                if (CustomFields == null)
                    CustomFields = "<CustomFields/>";

                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(this.CustomFields);
                XmlElement root = xmlDoc.DocumentElement;
                XmlElement field = root[name];
                if (value == null)
                {
                    if (field != null)
                    {
                        root.RemoveChild(field);
                    }
                }
                else
                {
                    if (field == null)
                    {
                        field = xmlDoc.CreateElement(name);
                        root.AppendChild(field);
                    }
                    field.InnerText = value;
                }

                this.CustomFields = xmlDoc.OuterXml;
            }

            #region IMessage Members


            IDictionary<string, string> IMessage.CustomFields
            {
                get
                {
                    if (customFields == null)
                        customFields = new MessagesRowCustomFields(this);
                    return customFields;
                }
            }

            public IFolder Folder
            {
                get 
                {
                    var header = MasterDataSet.Instance.MessageHeaders.FindByGuid(this.Guid);
                    if (header == null || header.RowState == System.Data.DataRowState.Deleted)
                        return null;
                    else
                        return header.Folder;
                }
            }

            public ICollection<IAttachment> Attachments
            {
                get 
                {
                    var header = MasterDataSet.Instance.MessageHeaders.FindByGuid(this.Guid);
                    if (header == null || header.RowState == System.Data.DataRowState.Deleted)
                        return null;
                    else
                        return header.Attachments;
                }
            }

            #endregion
        }
    }
 
}

